package ru.smc.hogwarts.servlets.students;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import ru.smc.hogwarts.model.House;
import ru.smc.hogwarts.model.Person;
import ru.smc.hogwarts.model.Role;
import ru.smc.hogwarts.model.Student;
import ru.smc.hogwarts.classes.EMF;
import ru.smc.hogwarts.classes.HashMd5;

public class StudentsAdd extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private String error = "";
	private String firstName = null;
	private String lastName = null;
	private int year = 0;
	private String status = null;
	private Date begin = null;
	private Date end = null;
	private int[] sum = {0,0,0,0};
	private HttpSession session;
	private boolean errHat;
	private String[] hat_marks;
	private int house_hat;
       
    public StudentsAdd() {
        super();
    }
    
    protected static int get (int[] array) {
    	Random random = new Random();
    	int rnd = 0;
    	do {
    		rnd = random.nextInt(array.length);
    	} while (array[rnd]==0);
        return array[rnd];
    }
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("error", error);
		
		session = request.getSession(true);
    	session.setAttribute("servletName", getServletName());
		
		List<Integer> dd = new ArrayList<Integer>();
		for (int i = 1; i<=31; i++) { dd.add(i); }
		request.setAttribute("dd", dd);
		
		List<Integer> yyyy = new ArrayList<Integer>();
		for (int i = 2000; i<=2020; i++) { yyyy.add(i); }
		request.setAttribute("yyyy", yyyy);
		
		if (error == "") {
			firstName = null;
			lastName = null;
			year = 0;
			status = null;
			begin = null;
			end = null;
			Arrays.fill(hat_marks, 0);
		}
		
		request.setAttribute("firstName", firstName);
		request.setAttribute("lastName", lastName);
		request.setAttribute("year", year);
		request.setAttribute("status", status);
		request.setAttribute("begin", begin);
		request.setAttribute("end", end);
		
		error = "";
		RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/pages/students/studentAdd.jsp");
		dispatcher.forward(request, response);
	}

	@SuppressWarnings("deprecation")
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		error = "";
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		
		try {			
			firstName = request.getParameter("firstName");
			if (firstName == "") error += "<span>П</span>оле \"Имя\" не должно быть пустым.<br>";
						
			lastName = request.getParameter("lastName");
			if (lastName == "") error += "<span>П</span>оле \"Фамилия\" не должно быть пустым.<br>";
			
			try {
				year = Integer.parseInt(request.getParameter("year"));
			} catch(NumberFormatException e) {}
			if (request.getParameter("year") == "") error += "<span>П</span>оле \"Курс\" не должно быть пустым.<br>";
			
			status = request.getParameter("status");
			if (status == "") error += "<span>П</span>оле \"Статус\" не должно быть пустым.<br>";
			
			if ((request.getParameter("beginDD") != "") && (request.getParameter("beginMM") != "") && (request.getParameter("beginYYYY") != "")) {
				begin = df.parse(request.getParameter("beginYYYY")+"-"+request.getParameter("beginMM")+"-"+request.getParameter("beginDD"));
				if (begin.getMonth()+1 != Integer.parseInt(request.getParameter("beginMM"))) 
					error += "<span>З</span>начение поля \"Дата зачисления\" введено некорректно. Такой даты не существует.<br>";
			} else if (request.getParameter("beginDD") == "") {
				error += "<span>З</span>начение поля \"Дата зачисления\" введено некорректно. День не должен быть пустым.<br>";
			} else if (request.getParameter("beginMM") == "") {
				error += "<span>З</span>начение поля \"Дата зачисления\" введено некорректно. Месяц не должен быть пустым.<br>";
			} else if (request.getParameter("beginYYYY") == "") {
				error += "<span>З</span>начение поля \"Дата зачисления\" введено некорректно. Год не должен быть пустым.<br>";
			}
			
			if ((request.getParameter("endDD") != "") && (request.getParameter("endMM") != "") && (request.getParameter("endYYYY") != "")) {
				end = df.parse(request.getParameter("endYYYY")+"-"+request.getParameter("endMM")+"-"+request.getParameter("endDD"));
				if (end.getMonth()+1 != Integer.parseInt(request.getParameter("endMM"))) 
					error += "<span>З</span>начение поля \"Дата окончания\" введено некорректно. Такой даты не существует.<br>";
			} else if (request.getParameter("endDD") == "") {
				error += "<span>З</span>начение поля \"Дата окончания\" введено некорректно. День не должен быть пустым.<br>";
			} else if (request.getParameter("endMM") == "") {
				error += "<span>З</span>начение поля \"Дата окончания\" введено некорректно. Месяц не должен быть пустым.<br>";
			}  else if (request.getParameter("endYYYY") == "") {
				error += "<span>З</span>начение поля \"Дата окончания\" введено некорректно. Год не должен быть пустым.<br>";
			}
			
			if (begin != null && end != null && end.before(begin)) {
				error += "<span>З</span>начение поля \"Дата окончания\" не может быть меньше значения поля \"Дата зачисления\".<br>";
			}
			
			hat_marks = request.getParameterValues("hat");
			int j = 0;
			Arrays.fill(sum, 0);
			for (int i = 0; i < hat_marks.length; i++) {  
			    if (hat_marks[i]!="")
			    	sum[j] = sum[j]+Integer.parseInt(hat_marks[i]);
			    else 
			    	errHat = true;
			    if (i%2 != 0)
			    	j++;
			}
			int max = 0;
			for (int i = 0; i < sum.length; i++) {
				if (sum[i]>max) {
					max = sum[i];
					house_hat = i+1;
				}
			}
			
			int[] randhat = {0,0,0,0};
			for (int i = 0; i < sum.length; i++) {
				if (max==sum[i]) {
					randhat[i]=i+1;
				}
			}
			house_hat = get(randhat);
			
			if (errHat) error += "<span>З</span>аполните все поля характеристик.<br>";
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		if (error == "") { 
			this.addStudent(firstName, lastName, begin, end, year, status, house_hat);
			response.sendRedirect(request.getContextPath() + "/students");
		} else if (error != "") {
			response.sendRedirect(request.getContextPath() + "/students/add");
		}
	}
	
	public void addStudent(String firstName, String lastName, 
			Date begin, Date end, int year, String status, int house_hat) {
		EntityManagerFactory emf = EMF.getInstance().getEMF();
    	EntityManager em = emf.createEntityManager();
		
		em.getTransaction().begin();
		
		Role role = new Role();
		role = em.find(Role.class, 6);
		
		House house = em.find(House.class, house_hat);
		
		Person person = new Person();
		
		person.setFirstName(firstName);
		person.setLastName(lastName);
		person.setPassword("");
		person.setLogin("");
		person.setHouse(house);
		person.setRole(role);
		
		em.persist(person);
		em.getTransaction().commit();
		em.getTransaction().begin();
		
		String login = "h"+house.getId()+"s"+person.getId();
		String hash_password = null;
		
		HashMd5 auth = new HashMd5();
		try {
			hash_password = auth.getHash(login);
		} catch (NoSuchAlgorithmException e) {}
		
		person.setPassword(hash_password);
		person.setLogin(login);
		
		em.persist(person);
		
		Student student = new Student();
		
		student.setPerson(person);
		student.setBegin(begin);
		student.setEnd(end);
		student.setYear(year);
		student.setStatus(status);
		
		em.persist(student);
		em.getTransaction().commit();
		
		em.close();
	}

}
